import win32ui
import win32print
import win32gui
import qrcode
import tempfile
import os, time

# 设置标签尺寸（单位：毫米）
paper_width = 10 * 6 + 7 * 2  # X
paper_length = 12  # Y
# 请确保打印机名称正确
printer_name = 'TSC TE344'
x_pos = [40, 180, 320, 460, 600, 750]
labal_index = 1


def get_x_pos(labal_index):
    if 1 <= labal_index <= len(x_pos):
        return x_pos[labal_index - 1]
    else:
        raise IndexError(f"labal_index {labal_index} 超出范围，应在1到{len(x_pos)}之间")


def set_printer_paper_size(printer_name, width_mm, length_mm):
    """设置打印机的纸张尺寸"""
    try:
        # 打开打印机
        hprinter = win32print.OpenPrinter(printer_name)

        # 获取当前打印机设置
        printer_info = win32print.GetPrinter(hprinter, 2)
        devmode = printer_info["pDevMode"]

        devmode.PaperWidth = int(width_mm * 10)
        devmode.PaperLength = int(length_mm * 10)

        # 设置为自定义纸张大小
        devmode.PaperSize = 256  # DMPAPER_USER表示自定义尺寸

        # 更新打印机设置
        printer_info["pDevMode"] = devmode
        win32print.SetPrinter(hprinter, 2, printer_info, 0)

        print(f"已设置打印机纸张尺寸: {width_mm}mm x {length_mm}mm")
        win32print.ClosePrinter(hprinter)
        return True

    except Exception as e:
        print(f"设置打印机纸张尺寸时出错: {e}")
        return False


def get_tsc_printer_info(printer_name=None):
    """获取TSC打印机纸张宽度信息"""
    printer_name = "TSC TE344"
    print(f"检查打印机: {printer_name}")
    # 获取打印机句柄
    hprinter = win32print.OpenPrinter(printer_name)
    try:
        properties = win32print.GetPrinter(hprinter, 2)
        # print(properties)
        if properties and 'pDevMode' in properties and properties['pDevMode']:
            devmode = properties['pDevMode']
            # 尝试获取纸张宽度（单位：0.1毫米）
            if hasattr(devmode, 'PaperWidth') and devmode.PaperWidth:
                width_mm = devmode.PaperWidth / 10.0
                Length_mm = devmode.PaperLength / 10.0
                print(f"纸张宽度: {width_mm} mm")
                print(f"纸张长度: {Length_mm} mm")

    except Exception as e:
        print(f"获取打印机信息时出错: {e}")
    finally:
        win32print.ClosePrinter(hprinter)


def generate_qr_code(data, size=3):
    """生成二维码图像"""
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=size,
        border=4,
    )
    qr.add_data(data)
    qr.make(fit=True)

    img = qr.make_image(fill_color="black", back_color="white")
    return img


def send_raw_data_to_printer(printer_name, data):
    """直接发送原始数据到打印机"""
    try:
        # print(f"尝试发送数据到打印机 '{printer_name}'...")
        hprinter = win32print.OpenPrinter(printer_name)
        try:
            # 开始打印作业
            # print("开始打印作业...")
            hjob = win32print.StartDocPrinter(hprinter, 1, ("Raw Data", None, "RAW"))
            win32print.StartPagePrinter(hprinter)

            # 发送数据
            if isinstance(data, str):
                data = data.encode('gbk')
            # print(f"发送数据长度: {len(data)} 字节")
            bytes_written = win32print.WritePrinter(hprinter, data)
            # print(f"已写入 {bytes_written} 字节到打印机")

            # 结束打印作业
            win32print.EndPagePrinter(hprinter)
            win32print.EndDocPrinter(hprinter)
            # print("打印作业已完成")
        except Exception as e:
            print(f"打印过程中出错: {e}")
            return False
        finally:
            win32print.ClosePrinter(hprinter)
        return True
    except Exception as e:
        print(f"打开打印机或发送数据时出错: {e}")
        return False


# def generate_qr_code():
#     rewind_cmd = "BACKFEED 150\n"
#     print("发送回退指令...")
#     if not send_raw_data_to_printer(printer_name, rewind_cmd):
#         print("发送回退指令失败")
distance = 150


def labal_rewind(distance):
    # rewind_cmd = f"BACKFEED {distance}\n"
    # print("发送回退指令...")
    # if not send_raw_data_to_printer(printer_name, rewind_cmd):
    #     print("发送回退指令失败")
    rewind_cmd = "BACKFEED 150\n"
    print("发送回退指令...")
    if not send_raw_data_to_printer(printer_name, rewind_cmd):
        print("发送回退指令失败")


def print_qr_code(data, printer_name='TSC TE344'):
    # printer_name = 'TSC TE344'
    # """打印二维码到指定打印机"""
    # qr_image = generate_qr_code(data)  # 生成二维码
    # hprinter = win32print.OpenPrinter(printer_name)
    # try:
    #     # 假设打印机分辨率为 203 DPI (TSC 常见分辨率)
    #     dpi = 203
    #     dots_per_mm = dpi / 25.4  # 每毫米点数
    #
    #     # 计算标签尺寸（单位：点）
    #     page_width_dots = int(paper_width * dots_per_mm)
    #     page_length_dots = int(paper_length * dots_per_mm)
    #
    #     print(f"标签尺寸: {paper_width}mm x {paper_length}mm")
    #     set_printer_paper_size(printer_name, paper_width, paper_length)
    #     get_tsc_printer_info(printer_name)
    #
    #     # 获取打印机信息
    #     printer_info = win32print.GetPrinter(hprinter, 2)
    #     # print(printer_info)
    #
    #     # 创建设备上下文
    #     hdc = win32ui.CreateDC()
    #     hdc.CreatePrinterDC(printer_name)
    #
    #     # 开始打印作业
    #     hdc.StartDoc("QR Code Print")
    #     hdc.StartPage()
    #
    #     # 将二维码保存为临时文件
    #     with tempfile.NamedTemporaryFile(suffix=".bmp", delete=False) as temp_file:
    #         temp_filename = temp_file.name
    #         qr_image.save(temp_filename, "BMP")
    #
    #     try:
    #         # 使用不同的方法加载位图
    #         hbitmap = win32gui.LoadImage(
    #             0, temp_filename, win32gui.IMAGE_BITMAP, 0, 0,
    #             win32gui.LR_LOADFROMFILE | win32gui.LR_CREATEDIBSECTION
    #         )
    #
    #         if not hbitmap:
    #             raise Exception("无法加载位图文件")
    #
    #         bmp = win32ui.CreateBitmapFromHandle(hbitmap)
    #
    #         # 获取位图尺寸
    #         bmp_size = bmp.GetSize()
    #         print(f"二维码位图尺寸: {bmp_size[0]} x {bmp_size[1]} 点")
    #
    #         # 获取打印页面尺寸
    #         printable_area = hdc.GetDeviceCaps(110), hdc.GetDeviceCaps(111)  # HORZRES, VERTRES
    #         physical_offset_x = hdc.GetDeviceCaps(112)  # PHYSICALOFFSETX
    #         physical_offset_y = hdc.GetDeviceCaps(113)  # PHYSICALOFFSETY
    #         physical_width = hdc.GetDeviceCaps(8)  # PHYSICALWIDTH
    #         physical_height = hdc.GetDeviceCaps(10)  # PHYSICALHEIGHT
    #
    #         print(f"可打印区域: {printable_area[0]} x {printable_area[1]} 点")
    #         print(f"物理偏移: {physical_offset_x} x {physical_offset_y} 点")
    #         print(f"物理尺寸: {physical_width} x {physical_height} 点")
    #
    #         # 计算二维码在标签上的位置（居中）
    #         # 考虑物理偏移量
    #         # x = physical_offset_x + (page_width_dots - bmp_size[0]) // 2
    #         # y = physical_offset_y + (page_length_dots - bmp_size[1]) // 2
    #         # x = x / 6
    #         # print(f"二维码位置: ({x}, {y})")
    #         # x = 20 +  140 * 5
    #         # y = -10
    #         x = get_x_pos(labal_index)
    #         y = -10
    #         print(f"二维码位置: ({x}, {y})")
    #
    #         # 创建内存DC并选择位图
    #         mem_dc = hdc.CreateCompatibleDC()
    #         mem_dc.SelectObject(bmp)
    #
    #         # 将位图从内存DC复制到打印机DC
    #         hdc.BitBlt((x, y), bmp_size, mem_dc, (0, 0), 0x00CC0020)  # SRCCOPY
    #         # 清理位图
    #         win32gui.DeleteObject(hbitmap)
    #
    #     finally:
    #         # 删除临时文件
    #         os.unlink(temp_filename)
    #
    #     # 结束打印作业
    #     hdc.EndPage()
    #     hdc.EndDoc()
    #
    # finally:
    #     win32print.ClosePrinter(hprinter)
    print(f"检查打印机: {printer_name}")
    global labal_index
    text_x = get_x_pos(labal_index)
    text_y = 4
    """设置打印机参数"""
    setup_cmds = [
        f"SIZE {paper_width} mm, {paper_length} mm",
        "DIRECTION 1",  # 打印方向
        "CLS",
        f"TEXT  {text_x},{text_y},\"1\",0,1,2,\"{data}\"",
        "SPEED 4",  # 打印速度
        "DENSITY 12",  # 打印浓度
        f"QRCODE {text_x + 10},{text_y + 40}, H, 3, A, 0, \"{data}\"",
        "PRINT 1",
    ]
    raw_data = "\n".join(setup_cmds) + "\n"
    print("发送指令...")
    if not send_raw_data_to_printer(printer_name, raw_data):
        print("发送指令失败")
    # print("二维码已发送到打印机")
    # time.sleep(1)  # 等待打印机处理
    print(labal_index)
    if labal_index < 6:
        rewind_cmd = "BACKFEED 170\n"
        print("发送回退指令...")
        if not send_raw_data_to_printer(printer_name, rewind_cmd):
            print("发送回退指令失败")
    labal_index = (labal_index % 6) + 1
